package com.subsequent.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.subsequent.pojo.Users;
import com.subsequent.service.UsersService;
import com.subsequent.utils.JwtService;
import com.subsequent.utils.Result;
import com.subsequent.utils.ValidateCodeUtils;
import com.subsequent.pojo.ForgotPasswordRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.util.StringUtils;
import org.springframework.security.crypto.bcrypt.BCrypt;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UsersService userService;
    @Autowired
    private ValidateCodeUtils validateCodeUtils;

    // 手机号正则表达式
    private static final String PHONE_PATTERN = "^1[3-9]\\d{9}$";

    @RequestMapping("/login")
    public Result login(@RequestParam String username,
                        @RequestParam String password){
        return userService.login(username,password);
    }
    @RequestMapping("/regist")
    public Result regist(@RequestBody Users user){
        return userService.regist(user);
    }

    /**
     * 发送手机验证码
     * @param phone 手机号
     * @return
     */
    @PostMapping("/sendCode")
    public Result sendCode(@RequestParam String phone) {
        // 验证手机号格式
        if (!Pattern.matches(PHONE_PATTERN, phone)) {
            return Result.error("手机号格式不正确");
        }
        // 生成6位数字验证码
        Integer code = ValidateCodeUtils.generateValidateCode(6);

        // 保存验证码到Redis
        boolean saved = validateCodeUtils.saveValidateCode(phone, code.toString());
        if (!saved) {
            return Result.error("验证码保存失败，请稍后重试");
        }

        // TODO: 这里需要调用短信服务发送验证码
        // 暂时模拟发送成功，实际项目中需要对接短信服务
        System.out.println("向手机号" + phone + "发送验证码：" + code);

        return Result.success("验证码发送成功");
    }

    /**
     * 手机号登录
     * @param phone 手机号
     * @param code 验证码
     * @return
     */
    @PostMapping("/loginByPhone")
    public Result loginByPhone(@RequestParam String phone, @RequestParam String code) {
        // 验证手机号格式
        if (!Pattern.matches(PHONE_PATTERN, phone)) {
            return Result.error("手机号格式不正确");
        }
        if (code == null || code.length() != 6) {
            return Result.error("验证码格式不正确");
        }

        // 验证验证码
        if (!validateCodeUtils.validateCode(phone, code)) {
            return Result.error("验证码错误或已过期");
        }

        // 查询用户信息
        Users user = userService.getOne(Wrappers.<Users>lambdaQuery().eq(Users::getPhone, phone));
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 生成token
        Map<String, Object> claimMaps = new HashMap<>();
        claimMaps.put("id", user.getId());
        claimMaps.put("username", user.getUsername());
        String token = JwtService.createToken(claimMaps);

        return Result.success("登录成功", token);
    }

    @PostMapping("/forgotPassword")
    public Result forgotPassword(@RequestBody ForgotPasswordRequest request) {
        // 1. 参数校验
        if (request == null || !StringUtils.hasText(request.getPhone()) ||
            !StringUtils.hasText(request.getCode()) || !StringUtils.hasText(request.getNewPassword())) {
            return Result.error("参数不能为空");
        }

        // 2. 校验验证码
        if (!validateCodeUtils.validateCode(request.getPhone(), request.getCode())) {
            return Result.error("验证码错误或已过期");
        }

        // 3. 查找用户
        Users user = userService.getOne(Wrappers.<Users>lambdaQuery().eq(Users::getPhone, request.getPhone()));
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 4. 更新密码（BCrypt加密存储）
        user.setPassword(BCrypt.hashpw(request.getNewPassword(), BCrypt.gensalt()));
        boolean updated = userService.updateById(user);

        if (updated) {
            return Result.success("密码重置成功");
        } else {
            return Result.error("密码重置失败，请稍后重试");
        }
    }
}
